package com.donger.mes.system.side.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.donger.mes.system.base.entity.MesBaseMaterial;
import com.donger.mes.system.base.service.MesBaseMaterialService;
import com.donger.mes.system.mes.enums.MesCodeEnums;
import com.donger.mes.system.side.dto.MesSideWarehouseOrderDTO;
import com.donger.mes.system.side.dto.MesSideWarehouseOrderItemDTO;
import com.donger.mes.system.side.entity.MesSideWarehouseOrder;
import com.donger.mes.system.side.entity.MesSideWarehouseOrderItem;
import com.donger.mes.system.side.enums.SideTypeEnums;
import com.donger.mes.system.side.mapper.MesSideWarehouseOrderMapper;
import com.donger.mes.system.side.service.MesSideWarehouseOrderItemService;
import com.donger.mes.system.side.service.MesSideWarehouseOrderService;
import com.donger.common.core.utils.BizException;
import com.donger.mes.utils.mes.MesUtils;
import lombok.AllArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.Valid;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
@AllArgsConstructor
public class MesSideWarehouseOrderServiceImpl implements MesSideWarehouseOrderService {
    private final MesSideWarehouseOrderMapper mesSideWarehouseOrderMapper;

    private final MesSideWarehouseOrderItemService mesSideWarehouseOrderItemService;

    private final MesBaseMaterialService mesBaseMaterialService;

    @Override
    public IPage<MesSideWarehouseOrder> page(Page<MesSideWarehouseOrder> page, Wrapper<MesSideWarehouseOrder> queryWrapper) {
        return mesSideWarehouseOrderMapper.selectPage(page, queryWrapper);
    }


    /**
     * 入库单
     * @param mesSideWarehouseOrderDTO
     */
    @Override
    @Transactional
    public void saveInputOrder(@Valid MesSideWarehouseOrderDTO mesSideWarehouseOrderDTO) {

        if (!mesSideWarehouseOrderDTO.getType().equals(SideTypeEnums.INPUT.getType())) {
            throw new BizException("入库类型不正确");
        }
        mesSideWarehouseOrderDTO.setOrderCode(MesUtils.getMesCode(MesCodeEnums.SIDEORDERCODE));

        MesSideWarehouseOrder mesSideWarehouseOrder = new MesSideWarehouseOrder();

        BeanUtil.copyProperties(mesSideWarehouseOrderDTO, mesSideWarehouseOrder);


        mesSideWarehouseOrderMapper.insert(mesSideWarehouseOrder);
        List<MesSideWarehouseOrderItemDTO> items = mesSideWarehouseOrderDTO.getItems();

        if(CollUtil.isEmpty(items)){
            throw new BizException("订单详情不能为空");
        }

        // 校验每一项中的数据
        List<MesSideWarehouseOrderItem> collect = items.stream()
                .map((MesSideWarehouseOrderItemDTO item) -> check(item,mesSideWarehouseOrder.getOrderCode()))
                .collect(Collectors.toList());

        mesSideWarehouseOrderItemService.saveBatch(collect);

    }

    /**
     * 出库单
     * @param mesSideWarehouseOrderDTO
     */
    @Override
    @Transactional
    public void saveOutputOrder(@Valid MesSideWarehouseOrderDTO mesSideWarehouseOrderDTO) {
        if (!mesSideWarehouseOrderDTO.getType().equals(SideTypeEnums.OUTPUT.getType())) {
            throw new BizException("入库类型不正确");
        }
        mesSideWarehouseOrderDTO.setOrderCode(MesUtils.getMesCode(MesCodeEnums.SIDEORDERCODE));
        MesSideWarehouseOrder mesSideWarehouseOrder = new MesSideWarehouseOrder();

        BeanUtil.copyProperties(mesSideWarehouseOrderDTO, mesSideWarehouseOrder);

        mesSideWarehouseOrderMapper.insert(mesSideWarehouseOrder);
        List<MesSideWarehouseOrderItemDTO> items = mesSideWarehouseOrderDTO.getItems();
        // 校验每一项中的数据
        List<MesSideWarehouseOrderItem> collect = items.stream()
                .map((MesSideWarehouseOrderItemDTO item) -> check(item,mesSideWarehouseOrder.getOrderCode()))
                .collect(Collectors.toList());

        mesSideWarehouseOrderItemService.saveBatch(collect);
    }

    @Override
    public MesSideWarehouseOrderDTO getOrderByCode(String orderCode) {
        MesSideWarehouseOrder mesSideWarehouseOrder = Optional.ofNullable(mesSideWarehouseOrderMapper.selectOne(Wrappers.<MesSideWarehouseOrder>lambdaQuery()
                .eq(MesSideWarehouseOrder::getOrderCode, orderCode))
        ).orElseThrow(() -> new BizException("订单不存在，无法执行"));

        MesSideWarehouseOrderDTO mesSideWarehouseOrderDTO = new MesSideWarehouseOrderDTO();

        BeanUtil.copyProperties(mesSideWarehouseOrder,mesSideWarehouseOrderDTO);

        List<MesSideWarehouseOrderItem> list = mesSideWarehouseOrderItemService.list(Wrappers.<MesSideWarehouseOrderItem>lambdaQuery()
                .eq(MesSideWarehouseOrderItem::getOrderCode, orderCode));
        if(CollUtil.isEmpty(list)){
            throw new BizException("订单详情数据为空,数据错误不能执行");
        }
        List<MesSideWarehouseOrderItemDTO> dtoList = list.stream().map(item -> {
            MesSideWarehouseOrderItemDTO mesSideWarehouseOrderItemDTO = new MesSideWarehouseOrderItemDTO();
            BeanUtil.copyProperties(item, mesSideWarehouseOrderItemDTO);

            return mesSideWarehouseOrderItemDTO;

        }).collect(Collectors.toList());

        mesSideWarehouseOrderDTO.setItems(dtoList);
        return mesSideWarehouseOrderDTO;
    }


    /**
     * 校验数据
     * @param item
     * @return
     */
    private MesSideWarehouseOrderItem check(@Valid MesSideWarehouseOrderItemDTO item,String orderCode){

        MesSideWarehouseOrderItem mesSideWarehouseOrderItem = new MesSideWarehouseOrderItem();
        BeanUtil.copyProperties(item,mesSideWarehouseOrderItem);
        mesSideWarehouseOrderItem.setOrderCode(orderCode);
        MesBaseMaterial mesBaseMaterial = Optional.ofNullable(mesBaseMaterialService.infoByCode(item.getMatCode()))
                .orElseThrow(() -> new BizException("物料" + item.getMatCode() + "不存在"));
        mesSideWarehouseOrderItem.setMatName(mesBaseMaterial.getMatName());
        return mesSideWarehouseOrderItem;
    }
}
